# !/usr/bin/env python
# encoding: utf-8


"""
  @author: gaogao
  @file: P_λ.py
  @time: 2022/3/18 10:13
  @desc:光谱扫描？？
"""
import time
import datetime
from utils.save_setting_2_ini import save_ini_info
from ATS.application.LASER_App.N7744C_App import N7744C_App
from ATS.application.LASER_App.L8164B_App import L8164B_App
from ATS.application.LASER_App.N7786C_App import N7786C_App
from ATS.datamanager import data_transfer_station as DataTransferStation
from utils.read_ini_2_dict import get_option_value, get_refrence_data
from utils.get_wave_power_util import get_wave_power_value
import csv
from collections import namedtuple
from gui import constant
from utils.log_util import loggings
from gui.driver.var_manager import VarManager
from utils.save_data_2_file import save_data_2_file
from database.db_interface import insert_chip

try:
    from ATS.switchdriver.LightSwitchDriver import LightSwitchDriver
except Exception as e:
    raise ValueError("光开关不在线，请重启光开关！")


def spectral_scan(para):
    result_data = namedtuple("result_data", "file_name,curve_type,y_invert,title,x_label,y_label,test_result")
    n7786c_app = N7786C_App("SS1")
    n7786c_app.set_trigger_conf_mode(2)
    n7744c_app = N7744C_App(para.n7744_setting["title"])
    l8164b_app = L8164B_App(para.l8164_setting["title"])
    inst_light = LightSwitchDriver.instance()

    time_stamp = datetime.datetime.now().strftime("%Y%m%d%H%M%S")

    toggle_optical_switch(inst_light)
    x_data, y_data, p_in = trigger_chain_loss_gc(n7744c_app, l8164b_app, para)
    # x_data,y_data,p_in = manual_loss_gc(n7744c_app,l8164b_app,para)
    # save_raw_data(para,result_data,x_data,y_data,time_stamp)

    time.sleep(2)
    wave_power_tuple = get_refrence_data()
    for wave_index in range(len(x_data)):
        y_data[wave_index] = float(p_in) - y_data[wave_index] - get_wave_power_value(x_data[wave_index],
                                                                                     wave_power_tuple)
    min_power = min(y_data)
    min_index = y_data.index(min_power)
    wave = x_data[min_index]
    loss_gc_list = [float(i) / 2 for i in y_data]
    try:
        file_name = f"{VarManager().diex}-{VarManager().diey}&{VarManager().subdie_name}&{para.subdie}&{para.test_item}_{time_stamp}"
        curve_title = f"{VarManager().diex}-{VarManager().diey}&{VarManager().subdie_name}&{para.subdie}&{para.test_item}"
        x_label = "WaveLength"
        y_label = "Power"
        post_curve_data(curve_title, loss_gc_list, file_name, result_data, x_data, x_label, y_label)
        # save_ini_info(constant.REMEMBER_VALUE, "remember_value", "wave_length", str(wave))
        # save_ini_info(constant.REMEMBER_VALUE, "remember_value", "power_value", str(min_power))
        loss_gc_section = f"{VarManager().diex}-{VarManager().diey}-{VarManager().subdie_name}_GC"
        save_ini_info(constant.REFRENCE_FILE, loss_gc_section, "wave_data", str(x_data))
        save_ini_info(constant.REFRENCE_FILE, loss_gc_section, "loss_gc", str(loss_gc_list))
        insert_data(loss_gc_list, para, x_data)
    except Exception as e:
        loggings.error("spectral_scan " + str(e))


def save_raw_data(para, result_data, x_data, y_data, time_stamp):
    loss_gc_section = f"{VarManager().diex}-{VarManager().diey}&{VarManager().subdie_name}&{para.subdie}_raw_data_{time_stamp}"
    curve_title = f"{VarManager().diex}-{VarManager().diey}&{VarManager().subdie_name}&{para.subdie}&{para.test_item}_raw_data"
    x_label = "WaveLength"
    y_label = "Power_raw_data"
    DataTransferStation.get_DTS().postarraydata("test",
                                                result_data(loss_gc_section, para.test_item, "line", True,
                                                            curve_title, x_label, y_label,
                                                            (x_data, y_data)))


def insert_data(loss_gc_list, para, x_data):
    chip_name = f"{VarManager().subdie_name}"
    wafer_name = VarManager().wafer_name
    shot_position = f"{VarManager().diex},{VarManager().diey}"
    shot_number = VarManager().shot_number
    chip_number = VarManager().subdie_number
    polarization_type = VarManager().polarization_type
    measurement_parameter = f"{para.subdie}&{para.test_item}"
    measurement_data = str([x_data, loss_gc_list])
    data_unit = ""
    data_type = "Curve"
    insert_chip(chip_name, wafer_name, shot_position, shot_number, chip_number, polarization_type,
                measurement_parameter, measurement_data, data_unit, data_type)


def post_curve_data(curve_title, loss_gc_list, file_name, result_data, x_data, x_label, y_label):
    DataTransferStation.get_DTS().postarraydata("test",
                                                result_data(file_name, "line", True,
                                                            curve_title, x_label, y_label,
                                                            (x_data, loss_gc_list)))


def toggle_optical_switch(inst_light):
    if not inst_light.is_connected:
        inst_light.connect()
    inst_light.set_all_switch("01", "05")
    time.sleep(1)
    loggings.info("spectral_scan " + str(inst_light.query_switch()))




def splicing_wave_length_trigger_chain():
    pass


def trigger_chain_loss_gc(n7744c_app, l8164b_app, para):
    n7744c_app.set_logging_state("STOP")
    if l8164b_app.get_sweep_status() == "+1":
        l8164b_app.stop_sweep()
    x_data = para.l8164_setting['wave_length']
    points = len(x_data)
    l8164b_app.set_power_unit()
    l8164b_app.set_power_value(para.l8164_setting["power_value"])
    time.sleep(int(para.l8164_setting["stable_time"]))
    p_in = l8164b_app.fetch_input_power()
    l8164b_app.set_sweep_mode()
    l8164b_app.query_sweep_pmax(para.l8164_setting['wave_length'][0], para.l8164_setting['wave_length'][-1])
    l8164b_app.set_repeat_mode()
    l8164b_app.set_wave_sweep_speed()
    l8164b_app.set_start_stop_step_wave(para.l8164_setting['wave_length'][0], para.l8164_setting['wave_length'][-1],
                                        float(para.l8164_setting['wave_length'][1]) - float(
                                            para.l8164_setting['wave_length'][0]))
    l8164b_app.trigger_config()
    l8164b_app.trigger_output()
    l8164b_app.trigger_input()
    l8164b_app.output_on()
    l8164b_app.set_wave_sweep_state()
    time.sleep(1)
    # n7744c_app.reset()
    n7744c_app.set_power_unit()
    n7744c_app.set_power_range(para.n7744_setting["power_range"])
    n7744c_app.set_auto_gain()
    n7744c_app.set_power_atim(para.n7744_setting["atim"])
    n7744c_app.trigger_input_mode()
    n7744c_app.set_power_wave_length(1310)
    n7744c_app.set_logging_points(points)
    n7744c_app.set_logging_state()
    time.sleep(2)
    # n7744c_app.tigger_status()
    l8164b_app.trigger()
    time.sleep(1)
    while True:
        state = n7744c_app.get_func_state()
        if state == "LOGGING_STABILITY,COMPLETE":
            y_data = n7744c_app.get_func_res()
            break
    y_data = [float(i) for i in y_data]
    if l8164b_app.get_sweep_status() == "+1":
        l8164b_app.stop_sweep()
    return x_data, y_data, p_in


def manual_loss_gc(n7744c_app, l8164b_app, para):
    l8164b_app.set_power_unit()
    l8164b_app.set_power_value(para.l8164_setting["power_value"])

    time.sleep(3)
    l8164b_app.output_on()

    p_in = l8164b_app.fetch_input_power()

    wave_list = para.l8164_setting['wave_length']

    n7744c_app.reset()
    n7744c_app.set_power_unit()
    n7744c_app.set_power_range_auto()

    n7744c_app.set_power_atim(para.n7744_setting["atim"])
    power_raw_data = []
    for wave in wave_list:
        l8164b_app.set_wave_length(wave)
        time.sleep(0.5)
        power = float(n7744c_app.get_power_value())
        power_raw_data.append(power)
    return wave_list, power_raw_data, p_in


spectral_scan(locals()["para"])
